/**
 * 存储基类
 * 定义所有存储类型的通用接口，支持同步和异步操作
 */
export class BaseStore {
  constructor(prefix = '') {
    this.prefix = prefix;
    this.isAsync = false; // 标识是否为异步存储
  }

  /**
   * 获取带前缀的键名
   * @param {string} key 原始键名
   * @returns {string} 带前缀的键名
   */
  getKey(key) {
    return this.prefix ? `${this.prefix}:${key}` : key;
  }

  /**
   * 设置值（同步版本）
   * @param {string} key 键名
   * @param {any} value 值
   * @param {Object} options 选项
   * @returns {boolean} 是否成功
   */
  set(key, value, options = {}) {
    throw new Error('set method must be implemented by subclass');
  }

  /**
   * 设置值（异步版本）
   * @param {string} key 键名
   * @param {any} value 值
   * @param {Object} options 选项
   * @returns {Promise<boolean>} 是否成功
   */
  async setAsync(key, value, options = {}) {
    // 默认实现：如果子类没有实现异步版本，则调用同步版本
    if (this.isAsync) {
      throw new Error('setAsync method must be implemented by async subclass');
    }
    return this.set(key, value, options);
  }

  /**
   * 获取值（同步版本）
   * @param {string} key 键名
   * @param {any} defaultValue 默认值
   * @returns {any} 值
   */
  get(key, defaultValue = null) {
    throw new Error('get method must be implemented by subclass');
  }

  /**
   * 获取值（异步版本）
   * @param {string} key 键名
   * @param {any} defaultValue 默认值
   * @returns {Promise<any>} 值
   */
  async getAsync(key, defaultValue = null) {
    // 默认实现：如果子类没有实现异步版本，则调用同步版本
    if (this.isAsync) {
      throw new Error('getAsync method must be implemented by async subclass');
    }
    return this.get(key, defaultValue);
  }

  /**
   * 删除值（同步版本）
   * @param {string} key 键名
   * @returns {boolean} 是否成功
   */
  remove(key) {
    throw new Error('remove method must be implemented by subclass');
  }

  /**
   * 删除值（异步版本）
   * @param {string} key 键名
   * @returns {Promise<boolean>} 是否成功
   */
  async removeAsync(key) {
    // 默认实现：如果子类没有实现异步版本，则调用同步版本
    if (this.isAsync) {
      throw new Error('removeAsync method must be implemented by async subclass');
    }
    return this.remove(key);
  }

  /**
   * 清空所有数据（同步版本）
   * @returns {boolean} 是否成功
   */
  clear() {
    throw new Error('clear method must be implemented by subclass');
  }

  /**
   * 清空所有数据（异步版本）
   * @returns {Promise<boolean>} 是否成功
   */
  async clearAsync() {
    // 默认实现：如果子类没有实现异步版本，则调用同步版本
    if (this.isAsync) {
      throw new Error('clearAsync method must be implemented by async subclass');
    }
    return this.clear();
  }

  /**
   * 检查键是否存在（同步版本）
   * @param {string} key 键名
   * @returns {boolean} 是否存在
   */
  has(key) {
    throw new Error('has method must be implemented by subclass');
  }

  /**
   * 检查键是否存在（异步版本）
   * @param {string} key 键名
   * @returns {Promise<boolean>} 是否存在
   */
  async hasAsync(key) {
    // 默认实现：如果子类没有实现异步版本，则调用同步版本
    if (this.isAsync) {
      throw new Error('hasAsync method must be implemented by async subclass');
    }
    return this.has(key);
  }

  /**
   * 获取所有键名（同步版本）
   * @returns {Array<string>} 键名数组
   */
  keys() {
    throw new Error('keys method must be implemented by subclass');
  }

  /**
   * 获取所有键名（异步版本）
   * @returns {Promise<Array<string>>} 键名数组
   */
  async keysAsync() {
    // 默认实现：如果子类没有实现异步版本，则调用同步版本
    if (this.isAsync) {
      throw new Error('keysAsync method must be implemented by async subclass');
    }
    return this.keys();
  }

  /**
   * 批量设置（异步版本）
   * @param {Object} items 键值对对象
   * @param {Object} options 选项
   * @returns {Promise<boolean>} 是否成功
   */
  async setManyAsync(items, options = {}) {
    try {
      const promises = Object.entries(items).map(([key, value]) => 
        this.isAsync ? this.setAsync(key, value, options) : this.set(key, value, options)
      );
      
      const results = await Promise.all(promises);
      return results.every(result => result === true);
    } catch (error) {
      console.error('BaseStore.setManyAsync error:', error);
      return false;
    }
  }

  /**
   * 批量获取（异步版本）
   * @param {Array<string>} keys 键名数组
   * @returns {Promise<Object>} 键值对对象
   */
  async getManyAsync(keys) {
    try {
      const results = {};
      
      for (const key of keys) {
        results[key] = this.isAsync ? await this.getAsync(key) : this.get(key);
      }
      
      return results;
    } catch (error) {
      console.error('BaseStore.getManyAsync error:', error);
      return {};
    }
  }

  /**
   * 批量删除（异步版本）
   * @param {Array<string>} keys 键名数组
   * @returns {Promise<boolean>} 是否成功
   */
  async removeManyAsync(keys) {
    try {
      const promises = keys.map(key => 
        this.isAsync ? this.removeAsync(key) : this.remove(key)
      );
      
      const results = await Promise.all(promises);
      return results.every(result => result === true);
    } catch (error) {
      console.error('BaseStore.removeManyAsync error:', error);
      return false;
    }
  }

  /**
   * 序列化数据
   * @param {any} value 要序列化的值
   * @returns {string} 序列化后的字符串
   */
  serialize(value) {
    try {
      return JSON.stringify({
        value,
        timestamp: Date.now(),
        type: typeof value
      });
    } catch (error) {
      console.error('Serialization error:', error);
      return null;
    }
  }

  /**
   * 反序列化数据
   * @param {string} serializedValue 序列化的字符串
   * @returns {any} 反序列化后的值
   */
  deserialize(serializedValue) {
    try {
      if (typeof serializedValue !== 'string') {
        return serializedValue;
      }
      
      const parsed = JSON.parse(serializedValue);
      return parsed.value !== undefined ? parsed.value : serializedValue;
    } catch (error) {
      // 如果解析失败，返回原始值
      return serializedValue;
    }
  }

  /**
   * 统一的操作方法，自动选择同步或异步
   * @param {string} method 方法名
   * @param {...any} args 参数
   * @returns {any|Promise<any>} 结果
   */
  async operate(method, ...args) {
    const asyncMethod = method + 'Async';
    
    if (this.isAsync && this[asyncMethod]) {
      return await this[asyncMethod](...args);
    } else if (this[method]) {
      return this[method](...args);
    } else {
      throw new Error(`Method ${method} not implemented`);
    }
  }
}